package com.topvision.face;

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PreviewCallback;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.kernal.demo.plateid.R;
import com.topvision.bureau.presenter.RegModePresenter;
import com.topvision.commomsdk.TouchInterface;
import com.topvision.commomsdk.uitl.AndroidUtils;
import com.topvision.commomsdk.uitl.CameraUtil;
import com.topvision.face.util.ARHandleState;
import com.topvision.face.util.GsonUtil;
import com.topvision.face.util.ThreadUtil;
import com.topvision.face.util.UploadUtil;
import com.topvision.face.view.DrawRectView;
import com.topvision.face.view.SVDraw;
import com.topvision.face.view.VideoPlayerView;
import com.topvision.face.vo.Face;
import com.topvision.face.vo.MatchedFace;
import com.topvision.face.vo.PeopleVo;
import com.topvision.face.vo.SiftSearchVO;
import com.topvision.voicesdk.BaseVoiceActivity;
import com.topvision.voicesdk.CommonVoice;
import com.topvision.voicesdk.VoiceInterface;

import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.objdetect.Objdetect;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FRActivity extends BaseVoiceActivity implements TouchInterface, VoiceInterface {
    public static final String DETECT_NO_FACE = "8464";
    public static final String DETECT_FACE = "0";
    // 检测手机移动
    private ShakeDetector detector;
    // camera视图
    private CameraView cameraView = null;
    // camera 父类控件
    FrameLayout mPreview;
    private static Object lock = new Object();
    TextView tips;
    private final float SCREEN_SHOT_RATIO = 0.3f;
    private final float SIMILARITY = 0.8f;

    private LinearLayout showResult1;
    private TextView showResultName1;
    private ImageView showResultPic1;

    private LinearLayout showResult2;
    private TextView showResultName2;
    private ImageView showResultPic2;

    private LinearLayout showResult3;
    private TextView showResultName3;
    private ImageView showResultPic3;
    private Bitmap bitmap;
    boolean savePicFlag = false;
    boolean realTimeMode = false;
    //识别类型,人脸、银行卡、身份
    int type = 0;
    boolean safeToTakePicture = true;
    Parameters params;
    Context context;
    int currentZoomValue = 0;
    private Camera.Size picModel_currentPreviewSize;
    private Camera.Size picModel_currentPicSize;
    private int height;
    private int width;
    private HashMap<Rect, String> rectHashMap;
    private DrawRectView drawRectView;
    private boolean cameraIsStop;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 设置外观
        getWindow().addFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN
                        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                        | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        // 设置视图
        setContentView(R.layout.fr_img);
        context = this;
        // 初始化页面组件
        initProperty();
        initOpenCv();
        initView();
        //createFaceView();
    }

    View faceResultView;
    TextView faceName;
    ImageView faceIv;
    TextView faceMode;

    private void initView() {

        LayoutInflater inflater = LayoutInflater.from(this);
        faceResultView = inflater.inflate(R.layout.take_photo_face_result, null);
        faceIv = (ImageView) faceResultView.findViewById(R.id.face_iv);
        faceName = (TextView) faceResultView.findViewById(R.id.face_name);
        WindowManager wm = this.getWindowManager();
        height = wm.getDefaultDisplay().getHeight();
        width = wm.getDefaultDisplay().getWidth();
    }


    /**
     * 上传图片，图片上传结束后记录日志
     *
     * @param byteArray
     */
    private String identifyFace(byte[] byteArray) {
        // TODO 这边会采取云从科技的API进行识别
        return UploadUtil.uploadData(byteArray, faceRecoginationUrl);
    }

    /**
     * 上传图片，图片上传结束后记录日志
     *
     * @param base64Face
     */
    private String identifyFace(String base64Face) {
        // TODO 这边会采取云从科技的API进行识别
        return UploadUtil.uploadBase64Data(base64Face, faceRecoginationUrl);
    }


    /**
     * 人脸检测
     *
     * @param byteArray
     * @return
     */
    private String detectFace(byte[] byteArray) {
        return UploadUtil.detectFace(byteArray, faceDetectUrl);
    }

    // 访问服务器的地址
    private static String server_host = null;
    // 人脸识别的接口
    private static String faceRecoginationUrl = null;
    private static String faceDetectUrl = null;
    private static String ImageUrl = null;
    private List<ShowResultBean> listDatas = new ArrayList<ShowResultBean>();
    private List<Bitmap> bitmapLists = new ArrayList<Bitmap>();
    private Map<String, Bitmap> bitmapMap = new HashMap<String, Bitmap>();

    /**
     * 初始化属性
     */
    @SuppressLint("NewApi")
    private void initProperty() {
        //默认精准模式
        realTimeMode = getIntent().getBooleanExtra(RegModePresenter.FACE_REAL_TIME_FLAG, true);
        faceMode = (TextView) findViewById(R.id.face_mode);
        if (realTimeMode) {
            faceMode.setText("实时模式");
        } else {
            faceMode.setText("拍照模式");
        }
        frameContainer = (FrameLayout) findViewById(R.id.frameContainer);
        // 初始化变量
        mPreview = (FrameLayout) findViewById(R.id.mPreview);

        DisplayMetrics dm = new DisplayMetrics();
        this.getWindowManager().getDefaultDisplay().getMetrics(dm);
        screenWidth = dm.widthPixels;
        screenHeight = dm.heightPixels;

        mSVDraw = (SVDraw) findViewById(R.id.mDraw);
        drawRectView = (DrawRectView) findViewById(R.id.drawRect);

        tipsTvs = new TextView[maxFaceNum];
        // tipsTv = (TextView)findViewById(R.id.infoTxt);
        tipsTvs[0] = (TextView) findViewById(R.id.infoTxt);
        tipsTvs[1] = (TextView) findViewById(R.id.infoTxt1);
        tipsTvs[2] = (TextView) findViewById(R.id.infoTxt2);
        // tipsTvs[3] = (TextView)findViewById(R.id.infoTxt3);
        // tipsTvs[4] = (TextView)findViewById(R.id.infoTxt4);
        //识别结果显示
        showResult1 = (LinearLayout) findViewById(R.id.include_show_result1);
        showResultName1 = (TextView) showResult1.findViewById(R.id.show_result_name);
        showResultPic1 = (ImageView) showResult1.findViewById(R.id.show_result_pic);

        ShowResultBean bean1 = new ShowResultBean();
        bean1.showResult = showResult1;
        bean1.showResultName = showResultName1;
        bean1.showResultPic = showResultPic1;
        listDatas.add(bean1);

        showResult2 = (LinearLayout) findViewById(R.id.include_show_result2);
        showResultName2 = (TextView) showResult2.findViewById(R.id.show_result_name);
        showResultPic2 = (ImageView) showResult2.findViewById(R.id.show_result_pic);

        ShowResultBean bean2 = new ShowResultBean();
        bean2.showResult = showResult2;
        bean2.showResultName = showResultName2;
        bean2.showResultPic = showResultPic2;
        listDatas.add(bean2);

        showResult3 = (LinearLayout) findViewById(R.id.include_show_result3);
        showResultName3 = (TextView) showResult3.findViewById(R.id.show_result_name);
        showResultPic3 = (ImageView) showResult3.findViewById(R.id.show_result_pic);
        ShowResultBean bean3 = new ShowResultBean();
        bean3.showResult = showResult3;
        bean3.showResultName = showResultName3;
        bean3.showResultPic = showResultPic3;
        listDatas.add(bean3);
        // 陀螺仪感应器
        detector = new ShakeDetector(FRActivity.this);

        // face++人脸识别接口
        // TODO

        // 创建截图存放目录
        File dir = new File(captureImgSavePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        server_host = this.getResources().getString(R.string.server_host);// "192.168.108.36";//221.6.207.216对外版本
        // faceRecoginationUrl = "http://" + server_host
        // + "/exp/faceRecog/identifyNew.do?groupName="
        // + getString(R.string.groupId);
        faceRecoginationUrl = "http://112.80.35.3:8828/face/recog/group/identify";
        faceDetectUrl = "http://112.80.35.3:8828/face/tool/detect";
        ImageUrl = "http://112.80.35.3:8828/face/clustering/face/query";
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }

    public void initCameraPreview() {
        cameraView = new CameraView(this);
        mPreview.addView(cameraView, FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (cameraView == null) {
            initCameraPreview();
        }
        setTouchInterfaceListener(this);
        setVoiceInterfaceListener(this);
        registerMyBroadcast();
//		if (detector != null) {
//			detector.registerOnShakeListener(shakeListener);
//			detector.start();
//		}
    }

    private void registerMyBroadcast() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.topvision.face.action");
        registerReceiver(MyReceiver, intentFilter);
    }


    private List<MatchedFace> convertFaceData(String uploadResult) {
        // 云从科技
        PeopleVo peopleVo = (PeopleVo) GsonUtil.JSONToObject(
                uploadResult, PeopleVo.class);
        if (peopleVo != null && peopleVo.getResult().equals("0")) {
            List<MatchedFace> list = new ArrayList<>();
            MatchedFace face = new MatchedFace();
            List<Face> faces = peopleVo.getFaces();
            if (faces != null && faces.size() > 0) {
                String faceId = faces.get(0).getFaceId();
                Bitmap bitmap = UploadUtil.getImageJpg(faces.get(0).getFaceId(), ImageUrl);
                bitmapMap.put(faceId, bitmap);
                String score = faces.get(0).getScore();
                float floatScore = Float.parseFloat(score);
                Log.e("floatScore", floatScore + "");
                if (Float.compare(floatScore, SIMILARITY) > 0) {
                    // 默认使用第一个face,识别度最高
                    face.setMatchedPersonName(faces.get(0).getFaceId());
                } else {
                    face.setMatchedPersonName(getString(R.string.unknow_person));
                }

            } else {
                face.setMatchedPersonName(getString(R.string.unknow_person));
            }
            list.add(face);
            return list;
        }
        return null;
    }

    @Override
    protected void onPause() {
        super.onPause();
//		if (detector != null) {
//			detector.unregisterOnShakeListener(shakeListener);
//			detector.stop();
//		}
        setTouchInterfaceListener(null);
        setVoiceInterfaceListener(null);
        mPreview.removeView(cameraView);
        cameraView.freeCameraResource();
        cameraView = null;
        unregisterReceiver(MyReceiver);

    }

    private static final int SENSOR_SHAKE = 10;
    private static final int SENSOR_NOT_SHAKE = 11;

    /**
     * 检测到摇晃后执行的回调方法
     */
    private ShakeDetector.OnShakeListener shakeListener = new ShakeDetector.OnShakeListener() {

        @Override
        public void onShake() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    isNeedDetect = false;
                    removeTips();
                    removeSignFace();
                }
            });
        }

        @Override
        public void onNotShake() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    isNeedDetect = true;
                }
            });
        }
    };

    /**
     * 是否需要检测人脸
     */
    private boolean isNeedDetect = true;
    // 识别结果背景图片所占比率设置
    private float backImageWidthRatio = 0.273f;
    private float backImageHeightRatio = 0.1f;
    // 屏幕size
    private int screenHeight, screenWidth;

    private int faceNumber;// 识别的人脸数
    private int preFaceNumber;
    private int maxFaceNum = 3;
    private TextView[] tipsTvs = null;

    private Map<Integer, SiftSearchVO> faceIndexPersonNameMap = null;
    private boolean hasResult = false;

    private Map<Integer, Integer> failCountMap = null;
    private static final int FAIL_COUNT = 2;

    // 是否已经截图
    private boolean hasCaptured = false;
    // private TextView tipsTv = null;

    // 人脸框的视图
    private SVDraw mSVDraw = null;

    private String captureImgSavePath = Environment
            .getExternalStorageDirectory().getAbsolutePath()
            + "/smartvision/faceRecognition/capture/";

    /**
     * opencv对图片进行转化
     *
     * @param rgbBuf
     * @param yuv420sp
     * @param width
     * @param height
     */
    static public void decodeYUV420SP(byte[] rgbBuf, byte[] yuv420sp,
                                      int width, int height) {
        final int frameSize = width * height;
        if (rgbBuf == null)
            throw new NullPointerException("buffer 'rgbBuf' is null");
        if (rgbBuf.length < frameSize * 3)
            throw new IllegalArgumentException("buffer 'rgbBuf' size "
                    + rgbBuf.length + " < minimum " + frameSize * 3);

        if (yuv420sp == null)
            throw new NullPointerException("buffer 'yuv420sp' is null");

        if (yuv420sp.length < frameSize * 3 / 2)
            throw new IllegalArgumentException("buffer 'yuv420sp' size "
                    + yuv420sp.length + " < minimum " + frameSize * 3 / 2);

        int i = 0, y = 0;
        int uvp = 0, u = 0, v = 0;
        int y1192 = 0, r = 0, g = 0, b = 0;

        for (int j = 0, yp = 0; j < height; j++) {
            uvp = frameSize + (j >> 1) * width;
            u = 0;
            v = 0;

            for (i = 0; i < width; i++, yp++) {
                y = (0xff & ((int) yuv420sp[yp])) - 16;
                if (y < 0)
                    y = 0;

                if ((i & 1) == 0) {
                    v = (0xff & yuv420sp[uvp++]) - 128;
                    u = (0xff & yuv420sp[uvp++]) - 128;
                }

                y1192 = 1192 * y;
                r = (y1192 + 1634 * v);
                g = (y1192 - 833 * v - 400 * u);
                b = (y1192 + 2066 * u);

                if (r < 0)
                    r = 0;
                else if (r > 262143)
                    r = 262143;
                if (g < 0)
                    g = 0;
                else if (g > 262143)
                    g = 262143;
                if (b < 0)
                    b = 0;
                else if (b > 262143)
                    b = 262143;

                rgbBuf[yp * 3] = (byte) (r >> 10);
                rgbBuf[yp * 3 + 1] = (byte) (g >> 10);
                rgbBuf[yp * 3 + 2] = (byte) (b >> 10);
            }
        }
    }

    private double[][] rectPercentVals = null;
    private boolean[] recognizeFlag = null;

    @Override
    public void dealWithVoice(String data) {
        if (data.contains(CommonVoice.VOICE_ZH_BACK)) {
            doBack();
        } else if (data.contains("拍照模式")) {
            switchFaceMode(false);
        } else if (data.contains("实时模式")) {
            switchFaceMode(true);
        } else if (data.contains("放大")) {
            doForwardTouch();
        } else if (data.contains("缩小")) {
            doBackwardTouch();
        }
        else if (data.contains(CommonVoice.VOICE_ZH_TAKE_PHOTO)) {
            //拍照模式下使用
            if (!realTimeMode) {
                takePhoto();
            }
        }
    }


    private void switchFaceMode(boolean realTimeMode) {
        Intent faceIntent = new Intent(context, FRActivity.class);
        faceIntent.putExtra(RegModePresenter.FACE_REAL_TIME_FLAG, realTimeMode);
        context.startActivity(faceIntent);
        finish();
    }

    // private int count = 0;

    private class MyPreviewCallback implements PreviewCallback {

        /**
         * 上次取帧时间
         */
        private long lastTaken = -1;

        /**
         * 调用api识别间隔
         */
        private static final long TAKEN_PERIOD = 1000;

        @SuppressLint("UseSparseArrays")
        @Override
        public void onPreviewFrame(final byte[] data, Camera camera) {
            if (!realTimeMode) {
                return;
            }

			/*
             * //如果手机在运动状态则不发射识别请求 if(!isNeedDetect){ return; }
			 */
            Camera.Size size = camera.getParameters().getPreviewSize();
            /**************************** 以下代码完成opencv对人脸的检测 *******************************/
            int mFrameHeight = size.height;
            int mFrameWidth = size.width;

            mYuvFrameData = new Mat(mFrameHeight + (mFrameHeight / 2),
                    mFrameWidth, CvType.CV_8UC1);
            mYuvFrameData.put(0, 0, data);
            mGray = mYuvFrameData.submat(0, mFrameHeight, 0, mFrameWidth);

            Mat faceImg = new Mat();
            int imgHeight = mFrameHeight;
            int imgWidth = mFrameWidth;
            float scale = 1.0f;

//            if (Math.max(mFrameHeight, mFrameWidth) > 640) {
//                scale = Math.min(480.0f / mFrameHeight, 640.0f / mFrameWidth);
//                imgHeight = Math.round(mFrameHeight * scale);
//                imgWidth = Math.round(mFrameWidth * scale);
//
//                faceImg = new Mat(imgHeight, imgWidth, CvType.CV_8UC1);
//                Imgproc.resize(mGray, faceImg, new org.opencv.core.Size(
//                        imgWidth, imgHeight));
//            } else {
            faceImg = mGray;
            //           }

            if (mAbsoluteFaceSize == 0) {
                mAbsoluteFaceSize = 64;
            }

            MatOfRect faces = new MatOfRect();

            if (mJavaDetector != null) {
                mJavaDetector.detectMultiScale(faceImg, faces, 1.1, 2,
                        Objdetect.CASCADE_DO_CANNY_PRUNING
                                | Objdetect.CASCADE_FIND_BIGGEST_OBJECT,
                        new org.opencv.core.Size(mAbsoluteFaceSize,
                                mAbsoluteFaceSize), new org.opencv.core.Size());
            }

            org.opencv.core.Rect[] facesArray = faces.toArray();

            /**************************** 以上代码完成opencv对人脸的检测 *******************************/

            if (facesArray != null && facesArray.length > 0) {
                // 以下代码是为了提高人脸的检测准确性
                List<org.opencv.core.Rect> facesList = new ArrayList<org.opencv.core.Rect>(
                        facesArray.length);
                int cnt = 0;
                for (int i = 0; i < facesArray.length; i++) {
                    Mat roi = new Mat(faceImg, facesArray[i]);
                    MatOfRect noses = new MatOfRect();
                    int noseSize = Math.min(facesArray[i].height,
                            facesArray[i].width) / 5;
                    mNoseDetector.detectMultiScale(roi, noses, 1.1, 2,
                            Objdetect.CASCADE_DO_CANNY_PRUNING
                                    | Objdetect.CASCADE_FIND_BIGGEST_OBJECT,
                            new org.opencv.core.Size(noseSize, noseSize),
                            new org.opencv.core.Size());

                    // 保留检测到鼻子的人脸
                    if (noses.total() <= 0 || facesArray[i] == null) {
                        continue;
                    }

                    org.opencv.core.Rect tmp = new org.opencv.core.Rect(
                            (int) (facesArray[i].x / scale),
                            (int) (facesArray[i].y / scale),
                            (int) (facesArray[i].width / scale),
                            (int) (facesArray[i].height / scale));

                    facesList.add(tmp);
                }

                facesArray = new org.opencv.core.Rect[facesList.size()];
                facesList.toArray(facesArray);

                /**************************** 以上代码完成opencv对人脸的检测 *******************************/
                // 检测到了人脸

                int maxLen = facesArray.length > maxFaceNum ? maxFaceNum
                        : facesArray.length;

				/* double[][] */
                rectPercentVals = new double[maxLen][4];
                // List<double[]> facePosList = new ArrayList<double[]>(maxLen);
                for (int i = 0; i < facesArray.length; i++) {
                    // 最多只识别maxFaceNum个人脸
                    if (i == maxFaceNum) {
                        break;
                    }
                    rectPercentVals[i][0] = facesArray[i].tl().x / mFrameWidth;// 左上角的x坐标位置比例
                    rectPercentVals[i][1] = facesArray[i].tl().y / mFrameHeight;// 左上角的y坐标位置比例
                    rectPercentVals[i][2] = facesArray[i].width * 1.0
                            / mFrameWidth;// 人脸框的宽度比例
                    rectPercentVals[i][3] = facesArray[i].height * 1.0
                            / mFrameHeight;// 人脸框的高度比例
                }
                // 当处于播放视频时就不就行人脸识别了
                // boolean playViewFlag = false;
                // if (playerView != null && playerView.isPlaying()) {
                // playViewFlag = true;
                // }

                // if (!playViewFlag) {
                // 将数组排序(按x位置)
                rectPercentVals = orderDoubleArray(rectPercentVals);

                // 标记出检测到的人脸
                boolean hasFace = detectionFaces(rectPercentVals);

                // 如果检测到人脸，则用face++进行识别
                if (hasFace) {
                    // 如果正在移动则返回
                    /*
                     * if(!isNeedDetect){ return; }
					 */
                    // 时间间隔太短
                    boolean flag = (System.currentTimeMillis() - lastTaken) > TAKEN_PERIOD
                            && isNeedDetect;
                    /*
                     * if(!flag){ return; }
					 */

                    YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21,
                            size.width, size.height, null);
                    // ByteArrayOutputStream baos = new
                    // ByteArrayOutputStream();
                    for (int i = 0; i < rectPercentVals.length; i++) {
                        // 最多只识别maxFaceNum个人脸
                        if (i == maxFaceNum) {
                            break;
                        }
                        // x,y,width,height是人脸框的位置区域
                        double x = rectPercentVals[i][0] * mFrameWidth;
                        double y = rectPercentVals[i][1] * mFrameHeight;// facesArray[i].tl().y;
                        int width = (int) (rectPercentVals[i][2] * mFrameWidth);
                        int height = (int) (rectPercentVals[i][3] * mFrameHeight);
                        // left,top,right,bottom表示上传给api的截图的位置区域
                        int left = (int) (x - SCREEN_SHOT_RATIO * width);// 往左移30%
                        if (left < 0) {
                            left = 0;
                        }
                        int top = (int) (y - SCREEN_SHOT_RATIO * height);// 往上移30%
                        if (top < 0) {
                            top = 0;
                        }
                        int right = (int) (x + width + SCREEN_SHOT_RATIO
                                * width);
                        if (right > mFrameWidth) {
                            right = mFrameWidth;
                        }
                        int bottom = (int) (y + height + SCREEN_SHOT_RATIO
                                * height);
                        if (bottom > mFrameHeight) {
                            bottom = mFrameHeight;
                        }

                        int index = i;
                        if (flag) {
                            // 设置当前的人脸检测位置
                            if (faceIndexPersonNameMap == null) {
                                faceIndexPersonNameMap = new HashMap<Integer, SiftSearchVO>(
                                        maxFaceNum);
                            }
                            // 已经有内容，则不再去取直接显示
                            // if (hasResult) {
                            // // System.out.println("hasResult...");
                            // // // do nothing
                            // } else {
                            // if (faceIndexPersonNameMap.containsKey(index)) {
                            // matchFace(null, null, mFrameWidth, mFrameWidth,
                            // (int) x, (int) y, width, height, index);
                            // } else {
                            synchronized (lock) {
                                // if (!hasResult) {
                                // hasResult = true;
                                matchFace(yuvImage, new Rect(left, top, right,
                                                bottom), mFrameWidth, mFrameHeight,
                                        (int) x, (int) y, width, height, index);
                                // }
                                // }
                            }
                            // }
                            lastTaken = System.currentTimeMillis();
                        } else {

                            // 重新计算识别文字的位置
                            SiftSearchVO vo = new SiftSearchVO();
                            if (faceIndexPersonNameMap != null
                                    && !faceIndexPersonNameMap.isEmpty()) {
                                SiftSearchVO siftSearchVO = faceIndexPersonNameMap
                                        .get(index);
                                if (siftSearchVO != null) {
                                    vo.setName(siftSearchVO.getName());
                                    vo.setContent(siftSearchVO.getContent());
                                }

                            } else {
                                vo.setName(getResources().getString(
                                        R.string.comparing));
                            }
                            vo.setxPos((float) x);
                            vo.setyPos((float) y);
                            vo.setWidth(width);
                            vo.setHeight(height);
                            vo.setFaceIndex(index);
                            showRecognizeResult(vo);
                        }
                    }
                }
                // } else {
                // removeSignFace();
                //
                // }
            } else {
                // Log.e("检测到人脸数", "没有检测到人脸");
                // 没有检测到人脸
                removeTips();
                removeSignFace();
                releasePlayer();
            }
        }

        /**
         * 对数组进行排序
         *
         * @param n
         */
        public double[][] orderDoubleArray(double[][] n) {
            for (int i = 0; i < n.length - 1; i++) {
                for (int j = 0; j < n.length - 1 - i; j++) {
                    double[] temp = null;
                    if (n[j][0] > n[j + 1][0]) {
                        temp = n[j + 1];
                        n[j + 1] = n[j];
                        n[j] = temp;
                    }
                }
            }
            return n;
        }

        private static final String UNKNOW_PERSON = "不认识";

        /**
         * 开始识别
         */
        private void matchFace(final YuvImage yuvImage, final Rect rect,
                               final int previewWidth, final int previewHeight,
                               final int left, final int top, final int width,
                               final int height, final int faceIndex) {

            if (yuvImage != null) {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                yuvImage.compressToJpeg(rect, 80, baos);// 只截取人脸部分
                final byte[] byteArray = baos.toByteArray();
                baos.reset();
                /**
                 * 启动比对线程
                 */
                ThreadUtil.executeAsyn(new Runnable() {
                    @Override
                    public void run() {

                        // 在线api交互
                        List<MatchedFace> faceList = startRecogination(byteArray);
                        if (faceList != null && faceList.size() > 0) {
                            final MatchedFace face = faceList.get(0);
                            if (null != face) {
                                SiftSearchVO vo = new SiftSearchVO();
                                // vo.setName(face.getMatchedPersonName());
                                // 如果是不认识则试的次数小于10时继续查找
                                if (UNKNOW_PERSON.equals(face
                                        .getMatchedPersonName())) {
                                    if (failCountMap == null) {
                                        failCountMap = new HashMap<Integer, Integer>();
                                    }
                                    Integer failCount = failCountMap
                                            .get(faceIndex);
                                    if (failCount == null
                                            || failCount < FAIL_COUNT) {
                                        failCountMap.put(faceIndex,
                                                failCount == null ? 1
                                                        : (failCount + 1));
                                        hasResult = false;
                                        return;
                                    }
                                }
                                vo.setxPos((float) left);
                                vo.setyPos((float) top);
                                vo.setWidth(width);
                                vo.setHeight(height);
                                vo.setFaceIndex(faceIndex);
                                vo.setName(face.getMatchedPersonName());
                                vo.setContent(face.getMatchedPersonDesc());

                                if (faceIndexPersonNameMap == null) {
                                    faceIndexPersonNameMap = new HashMap<Integer, SiftSearchVO>();
                                }
                                // 如果结果为不认识且已经有识别结果，则不将其放到结果map中
                                if (UNKNOW_PERSON.equals(face
                                        .getMatchedPersonName())
                                        && faceIndexPersonNameMap
                                        .containsKey(faceIndex)) {
                                    // don't write
                                } else {

                                    faceIndexPersonNameMap.put(faceIndex, vo);
                                }

                                // vo.setName(fullName);
                                Log.e(TAG, "run:--->" + vo.getName());
                                showRecognizeResult(vo);

                            } else { // 未匹配
                            }
                        }
                    }
                });
            } else {
                System.out.println("不在线访问api 只是重置识别结果的位置");
                // 不在线访问api 只是重置识别结果的位置
                // vo.setName(currentPersonName);
                if (faceIndexPersonNameMap != null
                        && !faceIndexPersonNameMap.isEmpty()) {
                    for (Map.Entry<Integer, SiftSearchVO> entry : faceIndexPersonNameMap
                            .entrySet()) {

                        System.out.println("Key = " + entry.getKey()
                                + ", Value = " + entry.getValue());

                    }
                    SiftSearchVO vo = new SiftSearchVO();
                    vo.setName(faceIndexPersonNameMap.get(faceIndex).getName());
                    vo.setContent(faceIndexPersonNameMap.get(faceIndex)
                            .getContent());
                    vo.setxPos((float) left);
                    vo.setyPos((float) top);
                    vo.setWidth(width);
                    vo.setHeight(height);
                    vo.setFaceIndex(faceIndex);
                    showRecognizeResult(vo);
                }

            }
        }

        /**
         * 将识别结果显示出来
         *
         * @param vo
         */
        //TODO 显示结果
        private void showRecognizeResult(final SiftSearchVO vo/*
                                                             * , final Long
															 * startTime
															 */) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // Log.d("RecordTime",
                    // "--start "+startTime+"..cost: "+(System.currentTimeMillis()-startTime));
                    if (vo != null) {
                        Log.e(TAG, "run:--->2" + vo.getName());
                        if (TextUtils.isEmpty(vo.getName())) {
                            return;
                        }
                        int faceIndex = vo.getFaceIndex();
                        ShowResultBean showResultBean = listDatas.get(faceIndex);
                        if (faceIndex >= faceNumber || faceIndex >= maxFaceNum) {
                            return;
                        }
                        // Log.d("ARActivity----handleMessage",
                        // "start...faceIndex.."+faceIndex+"..."+System.currentTimeMillis());
                        boolean isTop;
                        if (isNeedDetect) {
                            // signFace(vo);
                            // 优先显示在人脸上方（左对齐），
                            // 如果右边没法显示全，则与屏幕右对齐；如果人脸上方显示不下则在有脸下方显示；左右对齐参考上方
                            int backimageHeight = (int) (backImageHeightRatio * screenHeight);
                            int backimageWidth = (int) (backImageWidthRatio * screenWidth);
                            int initLeft = (int) vo.getxPos();
                            int initTop = (int) vo.getyPos() - backimageHeight
                                    - 10;

                            int textright = initLeft + backimageWidth + 10;
                            if (initTop > 0) {
                                isTop = true;
                                // 能在上方显示
                                if (textright > screenWidth) {
                                    // 右边超出屏幕,住左移，使右对齐屏幕
                                    initLeft = screenWidth - 10
                                            - backimageWidth;
                                }
                            } else {
                                // 不能在上方显示，显示在下方
                                isTop = false;
                                initTop = (int) (vo.getyPos() + vo.getHeight()) + 10;
                                if (initTop > screenHeight) {
                                    // 超出屏幕的高度
                                } else {
                                    // 能在上方显示
                                    if (textright > screenWidth) {
                                        // 右边超出屏幕,住左移，使右对齐屏幕
                                        initLeft = screenWidth - 10
                                                - backimageWidth;
                                    }
                                }
                            }

                            // 如果是"正在比对中"则直接显示，否则要经过faceIndexPersonNameMap的过滤
                            if (!vo.getName().equals("比对中...")) {
                                if (faceIndexPersonNameMap == null
                                        || faceIndexPersonNameMap
                                        .get(faceIndex) == null
                                        || !faceIndexPersonNameMap
                                        .get(faceIndex).getName()
                                        .equals(vo.getName())) {
                                    return;
                                }
                            }

                            if (showResultBean.showResult.getVisibility() == View.GONE) {
                                showResultBean.showResult.setVisibility(View.VISIBLE);
                            }
                            // int tempWidth = (int)0.25*screenWidth;

                            // long end = System.currentTimeMillis();
                            // Log.d("RecordTime",
                            // (end-startTime)+"--TOTAL "+startTime);
                            // 显示人脸结果
                            if (vo.getName().length() > 20) {
                                FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                                        (int) (0.25 * screenWidth),
                                        FrameLayout.LayoutParams.WRAP_CONTENT);
                                //TODO TOP设为了0 原值为initTOP
                                lp.setMargins(initLeft, initTop, 0, 0);// 只需设置左边距和上边距即可
                                showResultBean.showResult.setLayoutParams(lp);
                                showResultBean.showResult.setGravity(Gravity.LEFT
                                        | Gravity.CENTER_VERTICAL);
                                showResultBean.showResult.setPadding(5, 5, 5, 5);
                                showResultBean.showResultName.setText(vo.getName());
//								showResult.setTextColor(Color.BLACK);
//								showResult.setText(vo.getName());
                                //showResult.setText(vo.getName() + "\n"
//										+ vo.getContent());
                            } else {
                                FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                                        FrameLayout.LayoutParams.WRAP_CONTENT,
                                        FrameLayout.LayoutParams.WRAP_CONTENT);
                                //TODO TOP设为了原值为initTOP-65 原值为initTOP
                                //上方显示
                                if (isTop) {
                                    lp.setMargins(initLeft, initTop - 70, 0, 0);// 只需设置左边距和上边距即可
                                } else {//下方显示
                                    lp.setMargins(initLeft, initTop - 10, 0, 0);// 只需设置左边距和上边距即可
                                }
                                showResultBean.showResult.setLayoutParams(lp);
                                showResultBean.showResult.setPadding(20, 5, 20, 5);
                                showResultBean.showResult
                                        .setGravity(Gravity.CENTER_VERTICAL);
                                if (UNKNOW_PERSON.equals(vo.getName())) {
//									showResult.setTextColor(Color.RED);
                                    // 将框设置成红色
                                    if (recognizeFlag == null) {
                                        recognizeFlag = new boolean[rectPercentVals.length];
                                    }
                                    recognizeFlag[faceIndex] = true;
                                    findMultiFace(rectPercentVals,
                                            recognizeFlag);
                                } else {
//									showResult
//											.setTextColor(Color.BLACK);
                                }
                                // 最終顯示的結果
                                String info = "";
                                if (TextUtils.isEmpty(vo.getContent())) {
                                    info = vo.getName();
                                } else {
                                    // info = vo.getName() + "\n"
                                    // + vo.getContent();
                                    info = vo.getName();
                                }
                                Log.e(TAG, "run: " + vo.getName());
                                showResultBean.showResultName.setText(vo.getName());
//								showResult.setVisibility(View.VISIBLE);
                                // if (vo.getName().equals("范冰冰")) {
                                // // removeSignFace();
                                // List<String> urlList = new
                                // ArrayList<String>();
                                // urlList.add("/fbb.mp4");
                                //
                                // //
                                // urlList.add("http://jy520mio.com/upload/video/MIO.flv");
                                // VideoCache.setAssetManager(getAssets());
                                // showPlayer(urlList);
                                //
                                // }

                            }
//                            if (bitmapLists.size() > 0) {
//                                if (bitmapLists.size()-1 >= faceIndex) {
//                                    showResultBean.showResultPic.setImageBitmap(bitmapLists.get(faceIndex));
//                                }
//                            }
                            //根据名字找到对应的图片
                            if (bitmapMap.size() > 0 && !vo.getName().equals(UNKNOW_PERSON)) {
                                Bitmap bitmap = bitmapMap.get(vo.getName());
                                if (bitmap != null) {
                                    showResultBean.showResultPic.setImageBitmap(bitmap);
                                }
                            } else {
                                showResultBean.showResultPic.setImageResource(R.mipmap.photo);
                            }
                        }

                    }/*
                     * else{
					 * mOuter.get().showResult.setVisibility(View.GONE);
					 * // removeSignFace(); }
					 */
                }
            });
        }

        /**
         * 提交识别请求
         *
         * @return
         */
        private synchronized List<MatchedFace> startRecogination(
                byte[] byteArray) {
            // Log.e("size", "" + (byteArray.length / 1024 / 1024));
            fetchCount++;
            Log.d("FetchAPI", "start: " + System.currentTimeMillis() + ", "
                    + fetchCount);
            /**
             * 上传图片，图片上传结束后记录日志
             *
             * @param file
             */
            String uploadResult = identifyFace(byteArray);
            if (!TextUtils.isEmpty(uploadResult)) {
                // xunsiya
                // try {
                // JSONObject jsonObject = null;
                // String personName = "";
                // String desc = "";
                // if (!result.equals("unknown")) {
                // jsonObject = new JSONObject(result);
                // personName = jsonObject.getString("name");
                // desc = jsonObject.getString("desc");
                // }
                //
                // List<MatchedFace> list = new ArrayList<MatchedFace>();
                // MatchedFace face = new MatchedFace();
                // face.setMatchedPersonName(personName.equals("") ?
                // getResources()
                // .getString(R.string.unknow_person) : personName);
                // face.setMatchedPersonDesc(desc);
                // list.add(face);
                // Log.d("FetchAPI", "end: " + System.currentTimeMillis()
                // + ", " + fetchCount);
                // return list;
                // } catch (JSONException e) {
                // e.printStackTrace();
                // }
                // 云从科技
                return convertFaceData(uploadResult);
//                PeopleVo peopleVo = (PeopleVo) GsonUtil.JSONToObject(
//                        uploadResult, PeopleVo.class);
//                if (peopleVo != null) {
//                    List<MatchedFace> list = new ArrayList<MatchedFace>();
//                    MatchedFace face = new MatchedFace();
//                    List<Face> faces = peopleVo.getFaces();
//                    if (faces != null && faces.size() > 0) {
////                        //1-1识别图片暂时解决办法
////                        String faceId = PreferencesUtils.getString(FRActivity.this, "FaceId", "");
////                        if (faceNumber == 1 && !faceId.equals(faces.get(0).getFaceId())) {
////                            bitmapLists.clear();
////                        }
////                        PreferencesUtils.putString(FRActivity.this, "FaceId", faces.get(0).getFaceId());
////                        Log.e(TAG, "startRecogination: "+faces.get(0).getFaceId());
////                        //得到图片bitmap
////                        bitmap = UploadUtil.getImageJpg(faces.get(0).getFaceId(), ImageUrl);
////                        bitmapLists.add(bitmap);
//                        String faceId = faces.get(0).getFaceId();
//                        Bitmap bitmap = UploadUtil.getImageJpg(faces.get(0).getFaceId(), ImageUrl);
//                        bitmapMap.put(faceId, bitmap);
//                        String score = faces.get(0).getScore();
//                        float floatScore = Float.parseFloat(score);
//                        Log.e("floatScore", floatScore + "");
//                        if (Float.compare(floatScore, SIMILARITY) > 0) {
//                            // 默认使用第一个face,识别度最高
//                            face.setMatchedPersonName(faces.get(0).getFaceId());
//                        } else {
//                            face.setMatchedPersonName(getString(R.string.unknow_person));
//                        }
//
//                    } else {
//                        face.setMatchedPersonName(getString(R.string.unknow_person));
//                    }
//                    list.add(face);
//                    return list;
//                }
            }
            Log.d("FetchAPI", "end: " + System.currentTimeMillis() + ", "
                    + fetchCount);
            return null;
        }


        /**
         * 识别结果-人脸对象
         *
         * @author zhangyq
         */
//       public class MatchedFace {
//            private String matchedPersonName;
//
//            public void setMatchedPersonName(String matchedPersonName) {
//                this.matchedPersonName = matchedPersonName;
//            }
//
//            public void setMatchedPersonDesc(String matchedPersonDesc) {
//                this.matchedPersonDesc = matchedPersonDesc;
//            }
//
//            private String matchedPersonDesc;
//            private double matchedRatio;
//
//            public String getMatchedPersonDesc() {
//                return matchedPersonDesc;
//            }
//
//            public String getMatchedPersonName() {
//                return matchedPersonName;
//            }
//
//            public double getMatchedRatio() {
//                return matchedRatio;
//            }
//
//        }
    }

    private static int fetchCount = 0;

    /**
     * 检测人脸
     *
     * @param facesPercent 预览的图像数据
     */
    private boolean detectionFaces(double[][] facesPercent) {
        if (facesPercent != null && facesPercent.length > 0) {
            faceNumber = facesPercent.length;
            Log.e("检测到人脸数", faceNumber + "");
            if (faceNumber != 0) {
                if (faceNumber != preFaceNumber) {
                    removeTips();
                    preFaceNumber = faceNumber;
                }
                if (recognizeFlag == null) {
                    recognizeFlag = new boolean[facesPercent.length];
                }
                rectPercentVals = facesPercent;
                findMultiFace(facesPercent, recognizeFlag);
                return true;
            } else {
                removeTips();
                removeSignFace();
            }
        }
        return false;
    }

    /**
     * 发现并标记人脸
     */
    private void findMultiFace(final double[][] facesArray,
                               final boolean[] recogizeFlag) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mSVDraw.setVisibility(View.VISIBLE);
                // mSVDraw.drawRect(facesArray);
                mSVDraw.drawImage(facesArray, recogizeFlag);

            }
        });
    }

    /**
     * 将人脸标记移除
     */
    private void removeSignFace() {
        synchronized (this) {
            if (mSVDraw != null) {
                mSVDraw.setVisibility(View.GONE);
                mSVDraw.clearDraw();
            }
        }
    }

    /**
     * 将识别结果移除
     */
    private void removeTips() {
        faceIndexPersonNameMap = null;
        failCountMap = null;
        rectPercentVals = null;
        recognizeFlag = null;
        Log.d("debug", "hasCaptured=false");
        hasCaptured = false;
        hasResult = false;
//		if (tipsTvs != null) {
//			for (TextView tip : tipsTvs) {
//				tip.setVisibility(View.GONE);
//			}
//		}
        if (listDatas != null && listDatas.size() > 0) {
            for (ShowResultBean listData : listDatas) {
                listData.showResult.setVisibility(View.GONE);
            }
        }
        //清除扫描图片数据
        bitmapMap.clear();
//        bitmapLists.clear();
//        PreferencesUtils.putString(this, "FaceId", "");
    }

    public static final int PLAY_FINISH_STATUS = 101;

    public static final int MEDIA_PLAY_STATUS = 102;

    public static final int AUDIO_PLAY_STATUS = 103;
    private VideoPlayerView playerView = null;
    private FrameLayout frameContainer = null;
    private static int VIDEO_HEIGHT = 480;
    private static int VIDEO_WIDTH = 800;
    /**
     * 更新进度条
     */
    public Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            if (msg.what == PLAY_FINISH_STATUS) {
                releasePlayer();
            } else if (msg.what == MEDIA_PLAY_STATUS) {
                Log.i("arthread", "start to play video, show player views");
                View playerSurfaceView = findViewById(R.id.mSurfaceView);
                if (null == playerSurfaceView) {
                    return;
                }
                playerSurfaceView.setVisibility(View.VISIBLE);
                findViewById(R.id.pauseImg).setVisibility(View.VISIBLE);
                findViewById(R.id.playbar).setVisibility(View.VISIBLE);
                int width = findViewById(R.id.mSurfaceView).getWidth();
                int height = findViewById(R.id.mSurfaceView).getHeight();
                android.view.ViewGroup.LayoutParams lp = findViewById(
                        R.id.playframe).getLayoutParams();
                lp.width = width;
                lp.height = height;
                findViewById(R.id.playframe).setLayoutParams(lp);
            } else if (msg.what == AUDIO_PLAY_STATUS) {
                Log.i("arthread", "start to play audio, hide player views");
                View playerSurfaceView = findViewById(R.id.mSurfaceView);
                if (null == playerSurfaceView) {
                    return;
                }
                playerSurfaceView.setVisibility(View.GONE);
                findViewById(R.id.pauseImg).setVisibility(View.GONE);
                findViewById(R.id.playbar).setVisibility(View.GONE);
                frameContainer.removeView(playerView);
                ARHandleState.setState(ARHandleState.AR_PAUSE);

            }
        }

        ;
    };

    /**
     * 释放视频播放器
     */
    private void releasePlayer() {
        if (null != playerView) {
            frameContainer.removeView(playerView);
            playerView.release();
            playerView = null;
        }
    }

    @Override
    public void doForwardTouch() {
        Log.e("tvLog", "doForwardTouch");
        if (cameraView.getCameraInstance() != null) {
            //获取当前值
            Parameters parameters = cameraView.getCameraInstance().getParameters();
            currentZoomValue = parameters.getZoom();
            currentZoomValue = currentZoomValue + 5;
            CameraUtil.setZoomIn(cameraView.getCameraInstance(), currentZoomValue);

        }
    }

    @Override
    public void doBackwardTouch() {
        Log.e("tvLog", "doBackwardTouch");
        if (cameraView.getCameraInstance() != null) {
            //获取当前值
            Parameters parameters = cameraView.getCameraInstance().getParameters();
            currentZoomValue = parameters.getZoom();
            currentZoomValue = currentZoomValue - 5;
            CameraUtil.setZoomIn(cameraView.getCameraInstance(), currentZoomValue);
        }
    }

    @Override
    public void doClickTouch() {
        savePicFlag = !savePicFlag;
        takePhoto();
    }


    private void takePhoto() {
        if (!realTimeMode && cameraView != null && cameraView.getCameraInstance() != null && safeToTakePicture) {
            safeToTakePicture = false;
            cameraView.getCameraInstance().takePicture(null, null, cameraView);
        }
    }

    @Override
    public void doDoubleTouch() {

    }

    // ######################################################Camera相关类#################################################################

    public class CameraView extends SurfaceView implements
            SurfaceHolder.Callback, Camera.PictureCallback {

        public static final int MEDIA_TYPE_IMAGE = 1;
        public static final int MEDIA_TYPE_VIDEO = 2;
        private static final String TAG = "CameraDemo";
        private SurfaceHolder mHolder;
        private Camera mCamera;
        Context context;

        public CameraView(Context context) {
            super(context);
            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setKeepScreenOn(true);
            this.context = context;
        }

        /**
         * 获取照相机对象
         *
         * @param @return
         * @return Camera
         * @throws
         * @Title: getCameraInstance
         * @Description:
         */
        public Camera getCameraInstance() {
            if (mCamera == null) {
                try {
                    mCamera = Camera.open();
                    if (mCamera != null) {
                        setCameraParameters(mCamera);
                    }

                } catch (Exception e) {
                    Log.d(TAG, "camera is not available");
                    e.printStackTrace();
                }

            }

            return mCamera;
        }

        public void surfaceCreated(SurfaceHolder holder) {
            mCamera = getCameraInstance();
            try {
                if (mCamera != null) {
                    mCamera.setPreviewDisplay(holder);
                    mCamera.setPreviewCallback(new MyPreviewCallback());
                    mCamera.startPreview();
                } else {
                    Log.d(TAG, "camera is not avalible");
                }

            } catch (IOException e) {
                Log.d(TAG, "Error setting camera preview: " + e.getMessage());
                e.printStackTrace();
            }
        }


        private void setCameraParameters(Camera camera) {
            params = camera.getParameters();
            if (android.os.Build.VERSION.SDK_INT >= 21) {
                params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
            } else {
                params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
            }
            params.set("orientation", "landscape");
            List<Camera.Size> previews = params.getSupportedPreviewSizes();
//            for (Camera.Size size : previews) {
//                Log.e("tvLog", "width=" + size.width + ",height=" + size.height);
//            }
//            List<Camera.Size> pictures = params.getSupportedPictureSizes();
//            for (Camera.Size size : pictures) {
//                Log.e("tvLog", "width2=" + size.width + ",height2=" + size.height);
//            }

            Camera.Size currentPreviewSize = mCamera.getParameters().getPreviewSize();
            Camera.Size currentPicSize = mCamera.getParameters().getPictureSize();
            if (realTimeMode) {
                params.setPreviewSize(640, 480);
                params.setPictureSize(640, 480);
            } else {
                params.setPreviewSize(640, 480);
                params.setPictureSize(640, 480);
            }
            params.setPictureFormat(PixelFormat.JPEG); // 设置图片格式
            params.setJpegQuality(95); // 设置照片质量
            if (Build.BRAND.equals("TopVision") || Build.BRAND.equals("TopSmart") || Build.BRAND.equals("TopTrue")) { // 设备厂商 当只有眼镜才执行此代码
                params.setRecordingHint(true);
            }

            mCamera.setParameters(params);
            picModel_currentPreviewSize = mCamera.getParameters().getPreviewSize();
            picModel_currentPicSize = mCamera.getParameters().getPictureSize();
            Log.e("tvLog", "currentPreviewWidth=" + currentPreviewSize.width + ",currentPreviewHeight=" + currentPreviewSize.height);
            Log.e("tvLog", "currentPicWidth=" + currentPicSize.width + ",currentPicHight=" + currentPicSize.height);

        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            mHolder.removeCallback(this);
            if (mCamera != null) {
                mCamera.setPreviewCallback(null);
                mCamera.stopPreview();
                mCamera.release();
                mCamera = null;
            }

        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w,
                                   int h) {
            System.out.println("surfaceChanged");
        }


        public void freeCameraResource() {
            if (mCamera != null) {
                mCamera.setPreviewCallback(null);
                mCamera.stopPreview();
                mCamera.lock();
                mCamera.release();
                mCamera = null;
            }
        }

        private Paint mPaint;
        private Rect rect;

        private void initPaint() {
            mPaint = new Paint();
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(3);
            mPaint.setColor(Color.GREEN);
            rect = new Rect();
            rectHashMap = new HashMap<>();
        }

        @Override
        public void onPictureTaken(final byte[] bytes, Camera camera) {
            try {
                camera.stopPreview();
                cameraIsStop = true;
                initPaint();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //保存到本地
                        //  FileUtil.saveYuvToSdCardStorage(bytes);
                        final String detectFaceResult = detectFace(bytes);
                        Log.e("detectFaceResult", detectFaceResult);
                        if (!TextUtils.isEmpty(detectFaceResult)) {
                            PeopleVo detectFaceResultVo = (PeopleVo) GsonUtil.JSONToObject(
                                    detectFaceResult, PeopleVo.class);
                            if (DETECT_FACE.equals(detectFaceResultVo.getResult())) {
                                List<Face> detectFaces = detectFaceResultVo.getFaces();
                                for (final Face face : detectFaces) {
                                    String base64Face = face.getImg();
                                    System.out.println("X:" + face.getX() + "Y:" + face.getY() + "width:" + face.getWidth() + "height:" + face.getHeight());
//                                    mRect.set(face.getX(),face.getY(),face.getX()-face.getWidth(),face.getY()-face.getHeight());
//                                    if (picModel_currentPicSize != null) {
//                                        System.out.println(width+"-"+height+"-"+picModel_currentPicSize.width+"-"+ picModel_currentPicSize.height);
//                                        int realX = face.getX() * width / picModel_currentPicSize.width;
//                                        int realY = face.getY() * height / picModel_currentPicSize.height;
//                                        int realWidth = face.getWidth() * width / picModel_currentPicSize.width;
//                                        int realHeight = face.getHeight() * height / picModel_currentPicSize.height;
//                                    }
//                                    int realX = face.getX() * 800 / 1280;
//                                    int realY = face.getY() * 480 / 720;
//                                    int realWidth = face.getWidth() * 800 / 1280;
//                                    int realHeight = face.getHeight() * 480 / 720;
                                    int realX = face.getX() * width / picModel_currentPicSize.width;
                                    int realY = face.getY() * height / picModel_currentPicSize.height;
                                    int realWidth = face.getWidth() * width / picModel_currentPicSize.width;
                                    int realHeight = face.getHeight() * height / picModel_currentPicSize.height;
                                    Rect rect = new Rect();
                                    rect.set(realX, realY, realX + realWidth, realY + realHeight);
                                    System.out.println("faceId" + face.getFaceId());

                                    //进行识别
                                    final String result = identifyFace(base64Face);
                                    try {
                                        final List<MatchedFace> faces = convertFaceData(result);
                                        Log.i("Result", "the result = " + result);
                                        rectHashMap.put(rect, faces.get(0).getMatchedPersonName());
//                                        runOnUiThread(new Runnable() {
//                                            @Override
//                                            public void run() {
//                                                if (faces != null && faces.size() > 0) {
//                                                    String name = faces.get(0).getMatchedPersonName();
//                                                    AndroidUtils.showTips(context, name);
//                                                } else {
//                                                    AndroidUtils.showTips(context, "无人脸...");
//                                                }
//                                            }
//
//                                        });
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                                //显示识别结果
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {

                                        if (drawRectView != null) {
//                                            mSVDraw.drawRect(mPaint, rectHashMap);
                                            drawRectView.setVisibility(VISIBLE);
                                            drawRectView.drawRect(mPaint, rectHashMap);
                                        }

                                    }
                                });

                            } else {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        AndroidUtils.showTips(context, "无人脸");
                                    }
                                });
                            }
                        } else {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    AndroidUtils.showTips(context, "无网络连接");
                                }
                            });
                        }
                        Log.e("detectFaceResult", detectFaceResult);
                    }

                }).start();

            } catch (Exception e) {
                e.printStackTrace();
                safeToTakePicture = true;
            }
//            camera.startPreview();
            safeToTakePicture = true;
        }
    }

    // ######################################################Camera相关类
    // end#################################################################

    // #####################################################OpenCv 初始化
    // start#################################################################
    // opencv需要的so文件
    static {
        System.loadLibrary("opencv_java");
    }

    /**********************************************
     * opencv initial
     *******************************/
    // opencv data
    private static final String TAG = "LYC::Activity";
    private Mat mYuvFrameData;
    private Mat mGray;
    private File mCascadeFile;
    private CascadeClassifier mJavaDetector;
    private int mAbsoluteFaceSize = 0;
    private File mNoseCascadeFile;
    private CascadeClassifier mNoseDetector;
    DetectionBasedTracker mNativeDetector;

    /**
     * OpenCv初始化代码
     *
     * @param
     * @return void
     * @throws
     * @Title: initOpenCv
     * @Description:
     */
    private void initOpenCv() {
        try {
            // load cascade file from application resources
            InputStream is = getResources().openRawResource(
                    R.raw.haarcascade_frontalface_alt);
            File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
            mCascadeFile = new File(cascadeDir,
                    "haarcascade_frontalface_alt.xml");
            FileOutputStream os = new FileOutputStream(mCascadeFile);

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            is.close();
            os.close();

            mJavaDetector = new CascadeClassifier(
                    mCascadeFile.getAbsolutePath());
            if (mJavaDetector.empty()) {
                Log.e(TAG, "Failed to load cascade classifier");
                mJavaDetector = null;
            } else
                Log.i(TAG,
                        "Loaded cascade classifier from "
                                + mCascadeFile.getAbsolutePath());

            cascadeDir.delete();

        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "Failed to load cascade. Exception thrown: " + e);
        }

        try {
            // load cascade file from application resources
            InputStream is = getResources().openRawResource(
                    R.raw.haarcascade_mcs_nose);
            File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
            mNoseCascadeFile = new File(cascadeDir, "haarcascade_mcs_nose.xml");
            FileOutputStream os = new FileOutputStream(mNoseCascadeFile);

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            is.close();
            os.close();

            mNoseDetector = new CascadeClassifier(
                    mNoseCascadeFile.getAbsolutePath());
            if (mNoseDetector.empty()) {
                Log.e(TAG, "Failed to load cascade classifier"
                        + mNoseCascadeFile.getAbsolutePath());
                mNoseDetector = null;
            } else
                Log.i(TAG,
                        "Loaded cascade classifier from "
                                + mNoseCascadeFile.getAbsolutePath());

            cascadeDir.delete();

        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "Failed to load cascade. Exception thrown: " + e);
        }
    }

    // #####################################################OpenCv 初始化
    // end#################################################################

    // #####################################################视频播放相关类
    // start#################################################################

    /**
     * 显示视频播放器
     */
    @SuppressLint("NewApi")
    private void showPlayer(List<String> urlList) {
        if (null != playerView && playerView.isInPlayList(urlList)) {
            Log.i("arthread",
                    "Already in playlist, Ignore result, keep Playing...");
            return;
        }
        releasePlayer();
        playerView = new VideoPlayerView(urlList, this);

        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(VIDEO_WIDTH,
                VIDEO_HEIGHT);
        lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
        playerView.setLayoutParams(lp);
        playerView.setVisibility(View.VISIBLE);
        frameContainer.addView(playerView);
        // playerView.invalidate();
        frameContainer.invalidate();
    }

    // #####################################################视频播放相关类
    // end#################################################################

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == 27) {
            checkDoubleClick();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }


    private final int HANDLER_NO_FACE = 1;
    private final int HANDLER_CAMERA_BUTTON = 2;
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case HANDLER_NO_FACE:
                    AndroidUtils.showTips(getApplicationContext(), "无人脸");
                    break;
                case HANDLER_CAMERA_BUTTON:
                    firstClickTime = 0;
                    if (!doubleClickFlag) {
                        switchFaceMode(!realTimeMode);
                    }
                    break;
            }
        }
    };

    private BroadcastReceiver MyReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if ("com.topvision.face.action".equals(action)) {
                doBack();
            }
        }
    };


    private void doBack() {
//        if (faceResultView != null && faceResultView.getVisibility() == View.VISIBLE) {
//            faceResultView.setVisibility(View.GONE);
//            cameraView.getCameraInstance().startPreview();
//            removeSignFace();
//            drawRectView.clearDraw();
//            if (rectHashMap!=null) {
//                rectHashMap.clear();
//            }
//        } else

        if (cameraIsStop || (drawRectView != null && drawRectView.getVisibility() == View.VISIBLE)) {
            drawRectView.setVisibility(View.GONE);
            drawRectView.clearDraw();
            cameraView.getCameraInstance().startPreview();
            if (rectHashMap != null) {
                rectHashMap.clear();
            }
            cameraIsStop = false;
        } else {
            finish();
        }
    }


    long firstClickTime = 0;
    long secondClickTime = 0;
    boolean doubleClickFlag = false;

    public void checkDoubleClick() {
        if (firstClickTime > 0) {
            secondClickTime = SystemClock.uptimeMillis();
            if (secondClickTime - firstClickTime < 2000) {
                doubleClickFlag = true;
                CameraUtil.openOrCloseLight(cameraView.getCameraInstance());
            } else {
                doubleClickFlag = false;
            }
            firstClickTime = 0;
            return;
        }
        firstClickTime = SystemClock.uptimeMillis();
        doubleClickFlag = false;
        handler.removeMessages(HANDLER_CAMERA_BUTTON);
        handler.sendEmptyMessageDelayed(HANDLER_CAMERA_BUTTON, 2000);
    }
}
